﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.XPath;
using log4net;
using BMWSEMCRM.Model;
using BMWSEMCRM.NetUtils.Settings;
using BMWSEMCRM.Database;
using BMWSEMCRM.AppUtils;

namespace BMWSEMCRM.Process
{
    public class ImportFile
    {
        private static readonly ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public bool DelFile { get; set; }
        public string ImportFolder { get; set; }
        public string BackupLocation { get; set; }

        public bool Start()
        {
            if (!Directory.Exists(ImportFolder))
            {
                throw new DirectoryNotFoundException("ImportFolder not Found: " + ImportFolder);
            }
            // Get all files file start with T*
            var filePaths = Directory.GetFiles(ImportFolder, "T*");

            foreach (var xmlFileName in filePaths)
            {
                try
                {
                    logger.Debug("Start import: " + xmlFileName);

                    // create an XPathDocument object
                    var xmlPathDoc = new XPathDocument(xmlFileName);

                    // create a navigator for the xpath doc
                    var nav = xmlPathDoc.CreateNavigator();

                    var op = ParseOppoturnity(nav);

                    logger.Debug("Starting save to Database ...");

                    // delete or backup
                    if (DelFile)
                    {
                        logger.Debug("Delete: " + xmlFileName);
                        File.Delete(xmlFileName);
                    }
                    else
                    {
                        logger.Debug("Backup: " + xmlFileName);
                        var fileName = new FileInfo(xmlFileName).Name;
                        var fileNameDest = Path.Combine(BackupLocation, fileName);
                        File.Move(xmlFileName, fileNameDest);
                    }
                }
                catch (Exception ex)
                {
                    logger.Error(ex.Message, ex);
                }
            }

            return true;
        }

        private List<Oppoturnity> ParseOppoturnity(XPathNavigator nav)
        {
            var dealer = nav.SelectSingleNode("/DMSOpportunity/MessageBody/Dealer");
            var oppit = dealer.Select(nav.Compile("Opportunity"));

            var dealerId = GetSingleNodeValue(dealer, "LocalDealerID");

            // Mapping Database
            var mapConfig = DBAccess.GetSiteID(dealerId);
            var siteId = mapConfig["SITEID"] as string;
            var smanId = mapConfig["SMANID"] as string;
            var creationChannel = "BMW_" + siteId;

            var extsysId = AppConfig.GetSettingValue("ExternalSystemId", "");
            var commChannel = AppConfig.GetSettingValue("CommunicationChannel", "");
            var mcampId = AppConfig.GetSettingValue("MCAMPID", "");
            var heatLevel = AppConfig.GetSettingValue("HEATLEVEL", "");
            var ctrcd = AppConfig.GetSettingValue("CTRCD", "");
            var country = AppConfig.GetSettingValue("COUNTRY", "");
            var lang = AppConfig.GetSettingValue("LANG", "");
            var vehiType = "1";
            var isCompany = "0";


            var results = new List<Oppoturnity>();
            var tmpList = new List<Oppoturnity>();

            foreach (XPathNavigator val in oppit)
            {
                var leadId = GetSingleNodeValue(val, "OpportunityId");
                var name = GetSingleNodeValue(val, "OpportunityName");
                //var channel = GetSingleNodeValue(val, "Channel");
                var status = GetSingleNodeValue(val, "OpportunityStatus");
                var brand = GetSingleNodeValue(val, "OpportunityBrand");
                var lName = GetSingleNodeValue(val, "Customer/LastName");
                var fName = GetSingleNodeValue(val, "Customer/FirstName");
                var addr2 = GetSingleNodeValue(val, "Customer/Address/StreetAddress");
                var addr2e = GetSingleNodeValue(val, "Customer/Address/StreetAddressLine2");
                var pocd = GetSingleNodeValue(val, "Customer/Address/ZipCode");
                var wtel = GetSingleNodeValue(val, "Customer/MobilePhone");
                var htel = GetSingleNodeValue(val, "Customer/BusinessPhone");
                var fax = GetSingleNodeValue(val, "Customer/Fax");
                var email = GetSingleNodeValue(val, "Customer/Email");
                var salutCode = GetSingleNodeValue(val, "Customer/Salutation");
                var make = GetSingleNodeValue(val, "Customer/Product[TypeOfProductRelation='MAIN_VEHICLE']/Brand");
                var model = GetSingleNodeValue(val, "Customer/Product[TypeOfProductRelation='MAIN_VEHICLE']/Model");
                var tiMake = GetSingleNodeValue(val, "Customer/Product[TypeOfProductRelation='OWNER_OF']/Brand");
                var tiModel = GetSingleNodeValue(val, "Customer/Product[TypeOfProductRelation='OWNER_OF']/Model");
                //var country = GetSingleNodeValue(val, "Customer/Address/Country");
                var city = GetSingleNodeValue(val, "Customer/Address/Province");
                var header = GetSingleNodeValue(val, "OpportunityName");
                var body = GetSingleNodeInnerXML(val, "Activity");
                var planted = GetSingleNodeValue(val, "Activity/ActivityDueDate");
                var type = GetSingleNodeValue(val, "Activity/ActivityType");
                type = StringUtils.SubstringMax(type, 3);

                var actType = DBAccess.GetActType(type);

                var op = new Oppoturnity();
                op.SITEID = siteId;
                op.FNAME = fName;
                op.LNAME = lName;
                op.ADDR2 = addr2;
                op.ADDR2E = addr2e;
                op.PO = city;
                op.POCD = pocd;
                op.WTEL = wtel;
                op.HTEL = htel;
                //op.TEL3 = 
                op.EMAIL = email;
                op.FAX = fax;
                op.CGRPID = string.Empty;
                op.ORGTYPE = string.Empty;
                op.CTRCD = ctrcd;
                op.LANG = lang;
                op.SALUTCODE = salutCode;
                op.AGRP = string.Empty;
                op.BGROUP = string.Empty;
                op.EXTSYSID = extsysId;
                op.MAKE = make;
                op.MODEL = model;
                op.HEAT_LEVEL = heatLevel;
                op.LEAD_ID = leadId;
                op.COMM_CHANNEL = commChannel;
                op.CREATION_CHANNEL = creationChannel;
                op.PLANNED = planted;
                op.BODY = body;
                op.TYPE = type;
                op.ACTTYPE = actType;
                op.VEHTYPE = vehiType;
                op.MCAMP_ID = mcampId;
                op._Created = DateTime.Now.ToString(AppConfig.Constants.DEFAULT_DATETIME_FORMAT);
                op.ISCOMPANY = isCompany;
                op.SMANID = smanId;
                op.TIMAKE = tiMake;
                op.TIMODEL = tiModel;
                op.COUNTRY = country;
                op.HEADER = header;


                results.Add(op);
                tmpList.Add(op);

                if (tmpList.Count > 100)
                {
                    // Batch Insert
                    DBAccess.InsertOppoturnity(tmpList);
                    tmpList.Clear();
                }

            }

            if (tmpList.Count > 0)
            {
                // Batch Insert remaining !
                DBAccess.InsertOppoturnity(tmpList);
                tmpList.Clear();
            }

            return results;
        }

        private string GetSingleNodeValue(XPathNavigator nav, string xpath)
        {
            var node = nav.SelectSingleNode(nav.Compile(xpath));
            return node != null ? node.Value : string.Empty;
        }

        private string GetSingleNodeInnerXML(XPathNavigator nav, string xpath)
        {
            var node = nav.SelectSingleNode(nav.Compile(xpath));
            return node != null ? node.InnerXml : string.Empty;
        }

    }
}
